<?php

declare(strict_types=1);

namespace App\Middleware;

use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Router\Dispatched;
use Hyperf\HttpServer\Router\Handler;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use App\Common\Response\SystemCode;
class ValidateMiddleware implements MiddlewareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;


    /**
     * @var HttpResponse
     */
    protected $response;


    /**
     * @var RequestInterface
     */
    protected $request;



    /**
     * @Inject()
     * @var ValidatorFactoryInterface
     */
    protected $validationFactory;


    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request,ValidatorFactoryInterface $validationFactory)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
        $this->validationFactory = $validationFactory;
    }


    /**
     * 业务逻辑处理
     * @param ServerRequestInterface $request
     * @param RequestHandlerInterface $handler
     * @return ResponseInterface
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {

        try {
            $action = $this->request->getAttribute(Dispatched::class)->handler->callback;
            list($LongController, $method) = explode('@', $action);
            $controller = substr(strrchr($LongController,'\\'),1);
            $res = $this->paramsValidate($controller,$method,$this->request);
            if($res["code"] === -1){
                return $this->response->json([
                    'code' => SystemCode::SYSTEM_ERROR_PARAM_NULL,
                    'message' => $res["data"],
                ]);
            }
            return $handler->handle($request);

        } catch (\Exception $e){

            return $this->response->json([
                'code' => SystemCode::SYSTEM_ERROR_PARAM_NULL,
                'message' => $e->getMessage()
            ]);
        }
    }


    /**
     * 参数校验函数
     * @param $controller
     * @param $method
     * @param $request
     * @return array
     */
    private function paramsValidate($controller,$method,$request){
        $nameSpace = '\App\Vilidate\\'.$controller;
        $ValidateObj = (new $nameSpace)->$method;
        $validator = $this->validationFactory->make($request->post(),$ValidateObj["rule"],$ValidateObj["msg"]);
        if ($validator->fails()){
            // Handle exception
            $errorMessage = $validator->errors()->first();
            return ["code"=>-1,"msg"=>"校验不通过！","data"=>$errorMessage];
        }
        //校验通过
        return ["code"=>0,"msg"=>"校验通过！","data"=>[]];
    }
}
